package verify_code

import (
	"context"
	"errors"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/errcode"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/utils/captcha"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/utils/verifycode"
	userRepo "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/base/user"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/common/sms"
	pb "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/common"
	"git.myscrm.cn/golang/common/ykerrcode"
	"git.myscrm.cn/golang/stark/v4"
	"regexp"
	"time"
)

type VerifyCodeService struct {
	repo     sms.SmsCodeRepositoryIface
	userRepo userRepo.UserRepositoryIface
}

// NewVerifyCodeService 构造函数
func NewVerifyCodeService(
	repo sms.SmsCodeRepositoryIface,
	userRepo userRepo.UserRepositoryIface,
) VerifyCodeServiceIface {
	return &VerifyCodeService{
		repo:     repo,
		userRepo: userRepo,
	}
}

// GetCaptcha 获取验证码
func (v *VerifyCodeService) GetCaptcha(ctx context.Context, request *pb.GetCaptchaRequest) (*pb.GetCaptchaResponse, error) {
	// 生成验证码
	id, b64s, err := captcha.NewCaptcha(ctx).GenerateCaptcha()
	if err != nil {
		stark.Logger.Errorf(ctx, "NewVerifyCode,err:", err)
		return nil, ykerrcode.TogRPCError(errcode.USER_ACCOUNT_NOT_EXISIT, "用户不存在")
	}
	return &pb.GetCaptchaResponse{
		CaptchaId:    id,
		CaptchaImage: b64s,
	}, nil
}

// SendSmsCode 发送验证码
func (v *VerifyCodeService) SendSmsCode(ctx context.Context, request *pb.SendSmsRequest) (*pb.SendSmsResponse, error) {
	// 检查手机号是否达到发送验证码上限。
	verifyUtil := verifycode.NewVerifyCode(ctx)
	if verifyUtil.IsLocked(ctx, request.Mobile) {
		return nil, ykerrcode.TogRPCError(errcode.COMMON_SMS_CODE_MAX_SEND, "当日发送验证码次数已经达到上限")
	}
	// 校验参数 (目前是可选的 , 兼容小程序)
	if request.CaptchaId != "" && !(captcha.NewCaptcha(ctx).VerifyCaptcha(request.CaptchaId, request.CaptchaAnswer)) {
		return nil, ykerrcode.TogRPCError(errcode.COMMON_SMS_CODE_CHECK_CAPTHCHA, "图形验证码错误")
	}
	// 发送验证码（手机号验证码验证）
	result, _ := regexp.MatchString(`^(1[23456789]\d{9})$`, request.Mobile)
	if !result {
		return nil, ykerrcode.TogRPCError(errcode.COMMON_SMS_CODE_MOBILE_UNVALID, "错误的手机号码格式")
	}
	// 如果用户不存在，则不发送
	user, err := v.userRepo.GetUserByMobile(ctx, request.Mobile)
	if err != nil || user.Mobile == "" {
		return nil, ykerrcode.TogRPCError(errcode.COMMON_SMS_CODE_MOBILE_NOT_FOUND, "手机号码未注册")
	}
	// 发送短信
	code, err := verifyUtil.SendSMS(request.Mobile)
	if err != nil {
		stark.Logger.Errorf(ctx, "NewVerifyCode SendSMS error:%+v", err)
		return nil, ykerrcode.TogRPCError(errcode.COMMON_SMS_CODE_VERIFY_ERROR, "验证码错误")
	}
	verifyUtil.IncrSendSmsCnt(ctx, request.Mobile)

	// 保存记录
	// todo CreatedBy 获取用户id
	record := &sms.GfyxSmsCodePo{
		Mobile:     request.Mobile,
		Scene:      request.Scene,
		Code:       code,
		SendTime:   time.Now(),
		CreatedOn:  time.Now(),
		CreatedBy:  "",
		ModifiedOn: time.Now(),
		ModifiedBy: "",
		IsDeleted:  0,
	}

	_, err = v.repo.SaveSmsCode(ctx, record)
	if err != nil {
		stark.Logger.Errorf(ctx, "SaveSmsCode error:%+v", err)
		return nil, errors.New("保存发送记录失败")
	}

	return &pb.SendSmsResponse{}, nil
}
